package org.softmed.rest.generation.builders;

import java.util.List;

import org.softmed.reflection.utils.FieldInfo;
import org.softmed.reflection.utils.ReflectionUtil;
import org.softmed.rest.config.Handler;
import org.softmed.rest.config.HttpMethod;
import org.softmed.rest.config.MimeTypeHandler;
import org.softmed.rest.config.Module;
import org.softmed.rest.config.Parameter;
import org.softmed.rest.config.Resource;
import org.softmed.rest.generation.FieldCreationParameters;
import org.softmed.rest.generation.HandlerSuite;


public class NativeListRESTCreator {

	ReflectionUtil util = new ReflectionUtil();

	// String groovyScriptDir = "services.administration";
	// String genericGetListFieldXMLScript = ".list_get_xml";

	public void createRESTConfig(Class type, FieldInfo field, Class listType,
			FieldCreationParameters params) {
		// GET - remains the same
		Resource resource = createGetListAsXML(params.getModule(), params
				.getUri()
				+ "/{"
				+ params.getParameter()
				+ "}/"
				+ params.getRestFieldName(), params.getParameter(), params
				.getType(), params.getFieldInfo().getName(), params
				.getProviderName(), params.getXmlSuite(), params
				.getHandlerSuite());

		// POST
		HttpMethod method = createCreateNewNativeObjectToListTEXTMethod(
				resource, params.getType(), params.getParameter(), params
						.getFieldInfo().getName(), null, params
						.getProviderName(), params.getXmlSuite(), params
						.getHandlerSuite());

		// done
		createClearListMethod(resource, params.getParameter(),
				params.getType(), params.getFieldInfo().getName(), params
						.getProviderName(), params.getXmlSuite(), params
						.getHandlerSuite());

		// List Item REST Interface
		// get
		resource = createGetListItemText(params.getModule(), params.getUri()
				+ "/{" + params.getParameter() + "}/"
				+ params.getRestFieldName() + "/{index}", params.getType(),
				params.getParameter(), params.getFieldInfo().getName(),
				"index", params.getProviderName(), params.getXmlSuite(), params
						.getHandlerSuite());

		// post - text
		createSetNewObjectToParentList(resource, params.getType(), params
				.getParameter(), params.getFieldInfo().getName(), "index",
				listType, params.getProviderName(), params.getXmlSuite(),
				params.getHandlerSuite());

		// TODO TOTEST put - text
		createEditExistingObjectToParentList(resource, params.getType(), params
				.getParameter(), params.getFieldInfo().getName(), "index",
				listType, params.getProviderName(), params.getXmlSuite(),
				params.getHandlerSuite());

		// delete
		createRemoveListItemMethod(resource, params.getType(), params
				.getParameter(), params.getFieldInfo().getName(), "index",
				params.getProviderName(), params.getXmlSuite(), params
						.getHandlerSuite());
	}

	public void createEditExistingObjectToParentList(Resource resource,
			Class type, String uriParameter, String field,
			String childIndexParameter, Class childClass, String providerName,
			String xmlSuite, HandlerSuite handlerSuite) {

		HttpMethod method;

		method = new HttpMethod();
		method.setName("PUT");
		method.setActive(true);

		resource.getHttpMethods().add(method);

		Handler handler;

		MimeTypeHandler mime = new MimeTypeHandler();
		mime.setMimeType("text/plain");
		method.getMimeTypeHandlers().add(mime);

		handler = new Handler();
		handler.setActive(true);
		mime.setHandler(handler);

		handler.setPath(handlerSuite.getGenericEditNativeObjectInListText());

		handler.getParameters().add(
				new Parameter("provider-name", providerName));
		handler.getParameters().add(new Parameter("xml-suite", xmlSuite));
		handler.getParameters().add(
				new Parameter("class", type.getCanonicalName()));
		handler.getParameters().add(new Parameter("parameter", uriParameter));
		handler.getParameters().add(new Parameter("field", field));
		handler.getParameters().add(
				new Parameter("childIndexParameter", childIndexParameter));

	}

	private Resource createGetListItemText(Module module, String targetURI,
			Class type, String parameter, String field,
			String childIndexParameter, String providerName, String xmlSuite,
			HandlerSuite handlerSuite) {

		Resource resource;
		resource = new Resource();
		resource.setActive(true);
		resource.setTargetUri(targetURI);
		module.getResources().add(resource);

		HttpMethod method;
		MimeTypeHandler mime;
		Handler handler;

		method = new HttpMethod();
		method.setName("GET");
		method.setActive(true);

		resource.getHttpMethods().add(method);

		// set with XML
		mime = new MimeTypeHandler();
		mime.setMimeType("text/plain");

		method.getMimeTypeHandlers().add(mime);

		handler = new Handler();
		handler.setActive(true);

		handler.setPath(handlerSuite.getGetNativeObjectInListIndexText());

		mime.setHandler(handler);

		handler.getParameters().add(
				new Parameter("provider-name", providerName));
		handler.getParameters().add(new Parameter("xml-suite", xmlSuite));
		handler.getParameters().add(
				new Parameter("class", type.getCanonicalName()));
		handler.getParameters().add(new Parameter("parameter", parameter));
		handler.getParameters().add(new Parameter("field", field));
		handler.getParameters().add(
				new Parameter("childIndexParameter", childIndexParameter));

		return resource;
	}

	private HttpMethod createRemoveListItemMethod(Resource resource,
			Class type, String uriParameter, String fieldName,
			String childIndexParameter, String providerName, String xmlSuite,
			HandlerSuite handlerSuite) {
		HttpMethod method;
		Handler handler;

		// get
		method = new HttpMethod();
		method.setName("DELETE");
		method.setActive(true);

		resource.getHttpMethods().add(method);

		handler = new Handler();
		handler.setActive(true);

		handler.setPath(handlerSuite.getGenericRemoveListItem());
		method.setHandler(handler);

		handler.getParameters().add(
				new Parameter("provider-name", providerName));
		handler.getParameters().add(new Parameter("xml-suite", xmlSuite));
		handler.getParameters().add(
				new Parameter("class", type.getCanonicalName()));
		handler.getParameters().add(new Parameter("parameter", uriParameter));
		handler.getParameters().add(new Parameter("field", fieldName));
		handler.getParameters().add(
				new Parameter("childIndexParameter", childIndexParameter));

		return method;

	}

	public void createSetNewObjectToParentList(Resource resource, Class type,
			String uriParameter, String field, String childIndexParameter,
			Class childClass, String providerName, String xmlSuite,
			HandlerSuite handlerSuite) {

		HttpMethod method;

		method = new HttpMethod();
		method.setName("POST");
		method.setActive(true);

		resource.getHttpMethods().add(method);

		Handler handler;

		MimeTypeHandler mime = new MimeTypeHandler();
		mime.setMimeType("text/plain");
		method.getMimeTypeHandlers().add(mime);

		handler = new Handler();
		handler.setActive(true);
		mime.setHandler(handler);

		handler.setPath(handlerSuite.getGenericCreateNativeObjectToList());

		handler.getParameters().add(
				new Parameter("provider-name", providerName));
		handler.getParameters().add(new Parameter("xml-suite", xmlSuite));
		handler.getParameters().add(
				new Parameter("class", type.getCanonicalName()));
		handler.getParameters().add(new Parameter("parameter", uriParameter));
		handler.getParameters().add(new Parameter("field", field));
		if (childIndexParameter != null)
			handler.getParameters().add(
					new Parameter("childIndexParameter", childIndexParameter));

	}

	public HttpMethod createCreateNewNativeObjectToListTEXTMethod(
			Resource resource, Class type, String uriParameter, String field,
			String childIndexParameter, String providerName, String xmlSuite,
			HandlerSuite handlerSuite) {
		HttpMethod method;
		Handler handler;

		// post
		method = new HttpMethod();
		method.setName("POST");
		method.setActive(true);

		resource.getHttpMethods().add(method);

		MimeTypeHandler mime = new MimeTypeHandler();
		mime.setMimeType("text/plain");
		method.getMimeTypeHandlers().add(mime);

		handler = new Handler();
		handler.setActive(true);
		mime.setHandler(handler);

		handler.setPath(handlerSuite.getGenericCreateNativeObjectToList());

		handler.getParameters().add(
				new Parameter("class", type.getCanonicalName()));
		handler.getParameters().add(new Parameter("parameter", uriParameter));
		handler.getParameters().add(new Parameter("field", field));
		handler.getParameters().add(
				new Parameter("provider-name", providerName));
		handler.getParameters().add(new Parameter("xml-suite", xmlSuite));

		if (childIndexParameter != null)
			handler.getParameters().add(
					new Parameter("childIndexParameter", childIndexParameter));

		return method;

	}

	public HttpMethod createClearListMethod(Resource resource,
			String uriParameter, Class type, String field, String providerName,
			String xmlSuite, HandlerSuite handlerSuite) {
		HttpMethod method;
		Handler handler;

		// get
		method = new HttpMethod();
		method.setName("DELETE");
		method.setActive(true);

		resource.getHttpMethods().add(method);

		handler = new Handler();
		handler.setActive(true);

		handler.setPath(handlerSuite.getGenericClearList());
		method.setHandler(handler);

		handler.getParameters().add(
				new Parameter("class", type.getCanonicalName()));
		handler.getParameters().add(new Parameter("parameter", uriParameter));
		handler.getParameters().add(new Parameter("field", field));
		handler.getParameters().add(
				new Parameter("provider-name", providerName));
		handler.getParameters().add(new Parameter("xml-suite", xmlSuite));

		return method;

	}

	public Resource createGetListAsXML(Module module, String targetURI,
			String uriParameter, Class type, String fieldName,
			String providerName, String xmlSuite, HandlerSuite handlerSuite) {

		Resource resource;
		resource = new Resource();
		resource.setActive(true);
		resource.setTargetUri(targetURI);
		module.getResources().add(resource);

		createGenericGetListFieldXMLMethod(resource, uriParameter, type,
				fieldName, providerName, xmlSuite, handlerSuite);

		return resource;
	}

	public void createGenericGetListFieldXMLMethod(Resource resource,
			String uriParameter, Class type, String fieldName,
			String providerName, String xmlSuite, HandlerSuite handlerSuite) {
		HttpMethod method;
		MimeTypeHandler mime;
		Handler handler;

		// get
		method = new HttpMethod();
		method.setName("GET");
		method.setActive(true);

		resource.getHttpMethods().add(method);

		mime = new MimeTypeHandler();
		mime.setMimeType("application/xml");

		method.getMimeTypeHandlers().add(mime);

		handler = new Handler();
		handler.setActive(true);
		handler.setPath(handlerSuite.getListGetXml());

		mime.setHandler(handler);

		handler.getParameters().add(
				new Parameter("class", type.getCanonicalName()));
		handler.getParameters().add(new Parameter("parameter", uriParameter));
		handler.getParameters().add(new Parameter("field", fieldName));
		handler.getParameters().add(
				new Parameter("provider-name", providerName));
		handler.getParameters().add(new Parameter("xml-suite", xmlSuite));

	}

}